<?php
/**
 * 请求报告
 */
namespace App\Logic\Amazon\AdsApi;

use App\Models\AmazonAds\AdsDailyReport;
use App\Models\Basics\AmazonAccountAds;

class ReportRequest
{
    /**
     * 创建报告API--多报告一起，可设置多账号/单账号
     * @param array $params
     * [
     *  'accountId'=0 ,//可选，默认0
     *  'SP_AP' => [
     *      'timeUnit'=>'DAILY',//可选，默认'DAILY'
     *      'name'=>'',//必填
     *      'startDate'=>'',//必填
     *      'endDate'=>'' //必填
     *   ] ,
     *  'SD_AP' => [同'SP_AP'] ,
     *  'SB_C' => [同'SP_AP'] ,
     *  'ST_C' => [同'SP_AP']
     * ]
     * @return array
     */
    public static function createReport(array $params): array{

        //报告类型
        $adsType = AdsDailyReport::$_adsType;

        //验证报告参数
        $validateResult = self::_validateConfigParameters($adsType,$params);
        if(!$validateResult['status'])return $validateResult['info'];

        //Amazon账号
        $accountId = array_key_exists('accountId',$params) && $params['accountId'] ? $params['accountId'] : 0;
        $accounts = AmazonAccountAds::_getAccounts($accountId);
        $reDada = [];
        foreach ($accounts as $account){
            $accountId = $account->account_id;
            //广告API请求
            $config = self::_getConfiguration($accountId, $account->refresh_token, $account->amazon_account->aws_region);
            if(is_null($config)){
                $reDada[$accountId] = false;
                continue;
            }
            //获取对应账号下的市场区域（站点配置信息）
            $profiles = Report::listProfiles($config);
            foreach ($profiles as $profile){
                $profileId = $profile['profileId']; //配置id
                $countryCode = $profile['countryCode']; //国家编码
                foreach ($adsType as $typeId => $type){
                    if(array_key_exists($type,$params) && $params[$type]){
                        //请求报告，请求类文件（创建数据）
                        $serviceClass = __NAMESPACE__."\\ReportService\\".ucfirst($typeId);
                        $status = call_user_func_array([$serviceClass,'createReport'],[$config,$profileId,$countryCode,$params[$type]]);
                        $reDada[$accountId][$countryCode]['_createReportFor'.$type] = $status;
                        sleep(1);
                    }
                }
                sleep(10);
            }
            sleep(1);
        }
        return $reDada;
    }

    /**
     * 重新请求获取到的错误或失败的报告FAILED,ERROR
     * @param $model
     * @return array
     */
    public static function createReportForFailedAndError($model): array
    {
        $reDada = [];
        $accountId = $model->account_id;
        $countryCode = $model->country_code;
        if(!in_array($model->create_report_status,[4,5])){
            $reDada[$accountId][$countryCode]['status'] = '非FAILED/ERROR，无需重新请求';
            return $reDada;
        }
        $account = AmazonAccountAds::_getAccount($accountId);
        if(!$account){
            $reDada[$accountId][$countryCode]['account'] = '无账号授权信息';
            return $reDada;
        }
        $config = self::_getConfiguration($accountId, $account->refresh_token, $account->amazon_account->aws_region);
        if(is_null($config)){
            $reDada[$accountId][$countryCode]['config'] = false;
            return $reDada;
        }
        $profileId = $model->profile_id;
        $reportTypeId = $model->report_type_id;
        $type = AdsDailyReport::$_adsType[$reportTypeId];
        $params = [
            'name' => $model->name,
            'startDate' => $model->start_date,
            'endDate' => $model->end_date,
            'timeUnit' => $model->time_unit,
        ];
        //请求报告，请求类文件（创建数据）
        $serviceClass = __NAMESPACE__."\\ReportService\\".ucfirst($reportTypeId);
        $status = call_user_func_array([$serviceClass,'createReport'],[$config,$profileId,$countryCode,$params]);
        $reDada[$accountId][$countryCode]['_createReportFor'.$type] = $status;
        if($status){
            $model->delete();
        }
        sleep(1);
        return $reDada;
    }

    /**
     * 获取广告报告,并解析报告数据
     * @param $model
     * @return array
     */
    public static function getReport($model): array
    {
        $reDada = [];
        $accountId = $model->account_id;
        $countryCode = $model->country_code;
        if($model->create_report_status == 4 || $model->create_report_status == 5){
            $reDada[$accountId][$countryCode]['status1'] = '类型错误无法获取报告';
            return $reDada;
        }
        if($model->create_report_status == 3 && $model->download_parse_status == 1){
            $reDada[$accountId][$countryCode]['status2'] = '已正常下载&解析报告';
            return $reDada;
        }

        //报表(账号)
        $account = AmazonAccountAds::_getAccount($accountId);
        if(!$account){
            $reDada[$accountId][$countryCode]['account'] = '无账号授权信息';
            return $reDada;
        }
        //报表(配置)
        $config = self::_getConfiguration($accountId, $account->refresh_token, $account->amazon_account->aws_region);
        if(is_null($config)){
            $reDada[$accountId][$countryCode]['config'] = false;
            return $reDada;
        }
        $profileId = $model->profile_id; //账号配置id
        $reportId = $model->report_id; //报告文件id

        //1.获取报告
        $data = Report::getReport($config,$profileId,$reportId);
        if(is_null($data)){
            $reDada[$accountId][$countryCode]['_getReport'] = false;
        }else{
            if($data['status'] == 'COMPLETED'){
                $model->create_report_status = 3; //报告创建已完成
                $location = $data['url'];
                //2.下载报告
                $downloadData = Report::downloadReport($config,$profileId,$location);
                if(is_null($downloadData)){
                    $reDada[$accountId][$countryCode]['_downloadReport'] = false;
                }else{
                    $reDada[$accountId][$countryCode]['_downloadReport'] = true;
                    //3.解析报告，解析类（数据模型）
                    $serviceClass = __NAMESPACE__."\\ReportService\\".ucfirst($model->report_type_id);
                    $parseStatus = call_user_func_array([$serviceClass,'parse'],[$downloadData,$accountId,$countryCode]);
                    if($parseStatus){
                        $model->download_parse_status = 1; //报告解析成功
                        $reDada[$accountId][$countryCode]['_parseDownloadData'] = true;
                    }else{
                        $reDada[$accountId][$countryCode]['_parseDownloadData'] = false;
                    }
                }
                $model->save();
            }else{
                $reDada[$accountId][$countryCode]['_getReport'] = $data['status'];
            }
        }
        sleep(1);
        return $reDada;
    }

    /**
     * 获取配置信息
     * @param $accountId
     * @param $refreshToken
     * @param $region
     * @return array|null
     */
    private static function _getConfiguration($accountId, $refreshToken, $region): ?array
    {
        $requiredConfig = RequiredConfig::getInit();
        $config = $requiredConfig->configuration($accountId, $refreshToken, $region);
        if(!$config){
            report('[账号ID:'.$accountId.",_getConfiguration fail ]");
            return null;
        }
        return $config;
    }

    /**
     * 报告类型参数验证
     * @param $adsType
     * @param $params
     * @return array
     */
    private static function _validateConfigParameters($adsType,$params): array
    {
        $error = [];
        $adsTypeParamType = AdsDailyReport::$_adsTypeParamType;
        $n = 0;
        foreach ($adsType as $type){
            if(array_key_exists($type,$params) && $params[$type]){
                foreach ($adsTypeParamType as $paramType){
                    if(!array_key_exists($paramType,$params[$type]) || !$params[$type][$paramType]){
                        $error[$type][$paramType] = '必填项为空';
                    }
                }
            }else{
                $n++;
            }
        }
        if(count($adsType) == $n){
            return ['status' => false,'info' => ['error' => '广告类型为空']];
        }
        return ['status' => empty($error),'info' => [ empty($error) ? ['msg' => '参数无误'] : ['error' => $error]]];
    }

}
